package cn.coder.jdbc.session;

import java.sql.Connection;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.coder.jdbc.SqlTranction;

public final class DefaultSqlTranction implements SqlTranction {
	private static final Logger logger = LoggerFactory.getLogger(DefaultSqlTranction.class);

	private final Connection connection;
	private final SqlTranction[] tranctions;
	private final boolean hasMore;
	private final BaseSqlSession session;

	public DefaultSqlTranction(BaseSqlSession session, Connection conn, SqlTranction[] tranctions) throws SQLException {
		conn.setAutoCommit(false);
		this.session = session;
		this.connection = conn;
		this.tranctions = tranctions;
		this.hasMore = (tranctions != null && tranctions.length > 0);
	}

	@Override
	public Connection Connection() {
		return this.connection;
	}

	@Override
	public void commit() {
		try {
			this.connection.commit();
			if (this.hasMore) {
				for (SqlTranction sqlTranction : this.tranctions) {
					sqlTranction.commit();
				}
			}
			if (logger.isDebugEnabled())
				logger.debug("Tranction {} commited", this.hashCode());
		} catch (SQLException e) {

		} finally {
			close();
		}
	}

	@Override
	public void rollback(Exception e) {
		try {
			this.connection.rollback();
			if (this.hasMore) {
				for (SqlTranction sqlTranction : tranctions) {
					sqlTranction.rollback(e);
				}
			}
			if (logger.isDebugEnabled())
				logger.debug("Tranction " + this.hashCode() + " rollbacked", e);
		} catch (SQLException e1) {

		} finally {
			close();
		}
	}

	@Override
	public void close() {
		try {
			if (!this.connection.getAutoCommit()) {
				this.connection.setAutoCommit(true);
			}
			this.connection.close();
			this.session.endTranction(this);
			if (this.hasMore) {
				for (SqlTranction sqlTranction : tranctions) {
					sqlTranction.close();
				}
			}
			if (logger.isDebugEnabled())
				logger.debug("Tranction {} closed", this.hashCode());
		} catch (SQLException e) {

		}
	}

}
